package com.nbsaas.boot;

import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * OCR智能策略测试类
 * 用于验证不同场景下的策略选择
 */
public class OcrStrategyTest {

    public static void main(String[] args) {
        OcrStrategyTest test = new OcrStrategyTest();
        test.testStrategyScenarios();
    }

    /**
     * 测试不同场景下的策略选择
     */
    public void testStrategyScenarios() {
        System.out.println("=== OCR智能策略测试 ===\n");

        // 场景1: 完整提取 - 应该使用RULE_ONLY
        testScenario("场景1: 完整提取", 
            Arrays.asList("13812345678", "14:30去电", "120秒钟"),
            "期望策略: RULE_ONLY (所有字段都通过正则提取成功)");

        // 场景2: 高置信度 - 应该使用RULE_ONLY
        testScenario("场景2: 高置信度", 
            Arrays.asList("13812345678", "14:30去电", "其他信息", "更多信息", "额外信息"),
            "期望策略: RULE_ONLY (置信度较高)");

        // 场景3: 文字数量少 - 应该使用AI_ONLY
        testScenario("场景3: 文字数量少", 
            Arrays.asList("13812345678"),
            "期望策略: AI_ONLY (识别文字数量较少)");

        // 场景4: 混合场景 - 应该使用HYBRID
        testScenario("场景4: 混合场景", 
            Arrays.asList("13812345678", "14:30去电", "其他信息"),
            "期望策略: HYBRID (部分字段提取成功，需要AI辅助)");

        // 场景5: 无有效信息 - 应该使用AI_ONLY
        testScenario("场景5: 无有效信息", 
            Arrays.asList("无效信息", "其他内容"),
            "期望策略: AI_ONLY (无有效字段提取)");
    }

    /**
     * 测试单个场景
     * @param scenarioName 场景名称
     * @param ocrWords OCR识别的文字
     * @param expectedDescription 期望描述
     */
    private void testScenario(String scenarioName, List<String> ocrWords, String expectedDescription) {
        System.out.println(scenarioName);
        System.out.println("OCR识别内容: " + ocrWords);
        
        // 模拟规则提取
        CallInfo ruleResult = simulateRuleExtraction(ocrWords);
        System.out.println("规则提取结果: " + ruleResult);
        
        // 计算置信度
        double confidence = calculateConfidence(ocrWords, ruleResult);
        System.out.println("置信度分数: " + String.format("%.2f", confidence));
        
        // 确定策略
        String strategy = determineStrategy(ocrWords, ruleResult, confidence);
        System.out.println("选择策略: " + strategy);
        
        System.out.println("期望: " + expectedDescription);
        System.out.println("---");
    }

    /**
     * 模拟规则提取
     * @param words OCR识别的文字
     * @return 提取结果
     */
    private CallInfo simulateRuleExtraction(List<String> words) {
        CallInfo info = new CallInfo();
        
        Pattern phonePattern = Pattern.compile(OcrConfig.PHONE_PATTERN);
        Pattern timePattern = Pattern.compile(OcrConfig.TIME_PATTERN);
        Pattern durationPattern = Pattern.compile(OcrConfig.DURATION_PATTERN);

        for (String word : words) {
            if (info.phone == null && phonePattern.matcher(word).matches()) {
                info.phone = word;
            }

            Matcher timeMatcher = timePattern.matcher(word);
            if (info.callTime == null && timeMatcher.find()) {
                info.callTime = timeMatcher.group(1);
            }

            Matcher durationMatcher = durationPattern.matcher(word);
            if (info.duration == null && durationMatcher.find()) {
                String durationStr = durationMatcher.group(1);
                try {
                    info.duration = Integer.parseInt(durationStr);
                } catch (NumberFormatException e) {
                    System.err.println("时长格式转换失败: " + durationStr);
                }
            }
        }

        return info;
    }

    /**
     * 计算置信度
     * @param ocrWords OCR识别的文字列表
     * @param ruleResult 规则提取结果
     * @return 置信度分数
     */
    private double calculateConfidence(List<String> ocrWords, CallInfo ruleResult) {
        double score = 0.0;
        int totalFields = 3;
        int extractedFields = 0;

        if (ruleResult.phone != null) extractedFields++;
        if (ruleResult.callTime != null) extractedFields++;
        if (ruleResult.duration != null) extractedFields++;

        score += (double) extractedFields / totalFields * OcrConfig.FIELD_EXTRACTION_WEIGHT;

        if (ocrWords.size() >= OcrConfig.EXCELLENT_WORDS_COUNT) {
            score += OcrConfig.WORDS_COUNT_WEIGHT;
        } else if (ocrWords.size() >= OcrConfig.GOOD_WORDS_COUNT) {
            score += OcrConfig.WORDS_COUNT_WEIGHT * 0.5;
        }

        boolean hasPhoneLike = ocrWords.stream().anyMatch(word -> word.matches(".*\\d{11}.*"));
        boolean hasTimeLike = ocrWords.stream().anyMatch(word -> word.matches(".*\\d{2}:\\d{2}.*"));
        boolean hasDurationLike = ocrWords.stream().anyMatch(word -> word.matches(".*\\d+.*[秒分].*"));

        if (hasPhoneLike) score += OcrConfig.PHONE_QUALITY_BONUS;
        if (hasTimeLike) score += OcrConfig.TIME_QUALITY_BONUS;
        if (hasDurationLike) score += OcrConfig.DURATION_QUALITY_BONUS;

        return Math.min(score, 1.0);
    }

    /**
     * 确定策略
     * @param ocrWords OCR识别的文字
     * @param ruleResult 规则提取结果
     * @param confidence 置信度
     * @return 策略名称
     */
    private String determineStrategy(List<String> ocrWords, CallInfo ruleResult, double confidence) {
        if (!OcrConfig.ENABLE_SMART_STRATEGY) {
            return "HYBRID";
        }

        // 策略1: 字段完整性检查
        if (OcrConfig.ENABLE_COMPLETE_EXTRACTION_CHECK && isCompleteExtraction(ruleResult)) {
            return "RULE_ONLY";
        }

        // 策略2: 置信度评估
        if (OcrConfig.ENABLE_CONFIDENCE_EVALUATION && confidence >= OcrConfig.CONFIDENCE_THRESHOLD) {
            return "RULE_ONLY";
        }

        // 策略3: 文字数量和质量评估
        if (OcrConfig.ENABLE_WORDS_COUNT_CHECK && ocrWords.size() < OcrConfig.MIN_WORDS_COUNT) {
            return "AI_ONLY";
        }

        return "HYBRID";
    }

    /**
     * 检查是否完整提取了所有字段
     * @param ruleResult 规则提取结果
     * @return 是否完整
     */
    private boolean isCompleteExtraction(CallInfo ruleResult) {
        return ruleResult.phone != null && 
               ruleResult.callTime != null && 
               ruleResult.duration != null;
    }
} 